<?php

namespace App\WebSocket;

use Illuminate\Support\Facades\Cache;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use React\EventLoop\LoopInterface;

class WebSocketServer implements MessageComponentInterface
{
    protected $clients;

    protected $loop; // ReactPHP 的事件循环

    public function __construct(LoopInterface $loop)
    {
        $this->clients = new \SplObjectStorage;

        $this->loop = $loop;

        $this->loop->addPeriodicTimer(2, function () {
            foreach ($this->clients as $client) {
                if (isset($client->queryBody)) {
                    $cacheKey = 'okx-channel' . $client->queryBody['channel'] . '-' . $client->queryBody['instId'];

                    $data = Cache::get($cacheKey, '');

                    $client->send(json_encode([
                        'channel' => $client->queryBody['channel'],
                        'instId'  => $client->queryBody['instId'],
                        'time'    => date('Y-m-d H:i:s'),
                        'data'    => $data
                    ]));
                }
            }
        });
    }

    public function onOpen(ConnectionInterface $conn)
    {
        $this->clients->attach($conn);

        $data = json_encode([
            'event' => 'subscriptions',
            'message' => 'Success',
            'time' => date('Y-m-d H:i:s')
        ]);

        $conn->send($data);
    }

    public function onMessage(ConnectionInterface $from, $msg)
    {
        try {
            // 解析接收到的消息
            $decodedMsg = json_decode($msg, true);

            if (json_last_error() !== JSON_ERROR_NONE) {
                throw new \Exception('Invalid JSON format');
            }

            // 验证必要的字段
            if (!isset($decodedMsg['channel']) || !isset($decodedMsg['instId'])) {
                throw new \Exception('Missing required fields: channel and instId');
            }

            $from -> queryBody = [];

            $from -> queryBody[] = $decodedMsg;

        } catch (\Exception $e) {
            // 发送错误消息给客户端
            $errorMessage = [
                'event' => 'error',
                'message' => $e->getMessage(),
                'time' => date('Y-m-d H:i:s')
            ];
            $from->send(json_encode($errorMessage));
        }
    }

    public function onClose(ConnectionInterface $conn)
    {
        $this->clients->detach($conn);

        echo "客户端断开: {$conn->resourceId}\n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e)
    {
        echo "错误: {$e->getMessage()}\n";
        $conn->close();
    }
}
